package com.squirrel.auxiliary;

import com.squirrel.DataBeanConfig;
import com.squirrel.auxiliary.typeconversion.TypeConversion;
import com.squirrel.constant.DataDriver;
import com.squirrel.constant.QueryCondition;
import com.squirrel.facade.DataMedium;
import com.squirrel.facade.Update;
import com.squirrel.service.CreateDeleteSql;
import com.squirrel.service.CreateUpdateSql;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * @author wangyan
 */
@Repository
public class DataTypeConversionHandler implements IDataTypeConversion {

    @Autowired
    private DataBeanConfig dataBeanConfig;
    @Autowired
    private TypeConversion oracleTypeConversion;
    @Autowired
    private TypeConversion pgTypeConversion;
    @Autowired
    private TypeConversion mysqlTypeConversion;
    @Autowired
    private TypeConversion sqlServerTypeConversion;

    private static String driverClassName;

    private static final Logger log = LoggerFactory.getLogger(DataTypeConversionHandler.class);

    @Override
    public int saveDataTypeConversion(PreparedStatement ps, Map dataMedium, Map<String, String> columnTypeMap) throws SQLException {
        if (CollectionUtils.isEmpty(dataMedium)) {
            log.error("请输入要保存的字段");
            return 0;
        }
        if (CollectionUtils.isEmpty(columnTypeMap)) {
            log.error("要查询的表在数据库中不存在,oracle创建表时，如果表名称使用双引号包裹，请去掉双引号重新创建");
            return 0;
        }
        //更新语句的过滤条件
        LinkedList<String> getInputKey = new LinkedList<>(dataMedium.keySet());
        int totalSize = getInputKey.size();
        for (int i = 0; i < totalSize; i++) {
            if (i < getInputKey.size()) {
                //输入的字段
                String inputField = getInputKey.get(i);
                //得到字段类型
                String columnType = columnTypeMap.get(inputField);
                if (StringUtils.isEmpty(columnType)) {
                    log.error("要保存的字段{}在表中不存在,请核实建表语句", inputField);
                    return 0;
                }
                try {
                    driverClassName = dataBeanConfig.getDriverClassName();
                    if (DataDriver.ORACLE_DRIVER.equals(driverClassName)) {
                        oracleTypeConversion.dataConversion(ps, columnType, dataMedium, inputField, i);
                    } else if (DataDriver.PG_DRIVER.equals(driverClassName)) {
                        pgTypeConversion.dataConversion(ps, columnType, dataMedium, inputField, i);
                    } else if (DataDriver.SQLSERVER_DRIVER.equals(driverClassName)) {
                        sqlServerTypeConversion.dataConversion(ps, columnType, dataMedium, inputField, i);
                    } else if (DataDriver.MYSQL_DRIVER.equals(driverClassName)) {
                        mysqlTypeConversion.dataConversion(ps, columnType, dataMedium, inputField, i);
                    }
                } catch (Exception e) {
                    log.error("字段{}类型转换错误{}", inputField, e);
                    e.getMessage();
                }
            }
        }
        return totalSize;
    }

    @Override
    public void updateDataTypeConversion(PreparedStatement ps, Update update,
                                         Map<String, String> columnTypeMap) throws SQLException {
        CreateUpdateSql createUpdateSql = update.getCreateUpdateSql();
        DataMedium dataMedium = createUpdateSql.getDataMedium();
        if (!Objects.isNull(dataMedium) && !dataMedium.isEmpty()) {
            //写了哪些字段更新哪些
            for (Object key : dataMedium.keySet()) {
                Object value = dataMedium.get(key);
                dataMedium.put((String) key, value);
            }
        }
        //where 条件
        int fieldSize = this.saveDataTypeConversion(ps, dataMedium, columnTypeMap);
        List<Map<String, Object>> whereFilterList = createUpdateSql.getWhereFilterList();
        List<Map<String, Object>> andFilterList = createUpdateSql.getAndFilterList();
        if (!whereFilterList.isEmpty() && andFilterList.isEmpty()) {
            andFilterList.addAll(whereFilterList);
        }
        for (int i = 0; i < andFilterList.size(); i++) {
            Map<String, Object> stringObjectMap = andFilterList.get(i);
            //获取字段
            String field = (String) andFilterList.get(i).get("field");
            //获取字段类型
            String columnType = columnTypeMap.get(field);
            String condition = (String) andFilterList.get(i).get("condition");
            if (condition.equalsIgnoreCase(QueryCondition.SQL_IN)) {
                continue;
            }
            try {
                driverClassName = dataBeanConfig.getDriverClassName();
                if (DataDriver.ORACLE_DRIVER.equals(driverClassName)) {
                    oracleTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i + fieldSize);
                } else if (DataDriver.PG_DRIVER.equals(driverClassName)) {
                    pgTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i + fieldSize);
                } else if (DataDriver.SQLSERVER_DRIVER.equals(driverClassName)) {
                    sqlServerTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i + fieldSize);
                } else if (DataDriver.MYSQL_DRIVER.equals(driverClassName)) {
                    mysqlTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i + fieldSize);
                }
            } catch (Exception e) {
                log.error("字段{}类型转换错误{}", field, e);
                e.getMessage();
            }
        }
    }

    @Override
    public void deleteDataTypeConversion(PreparedStatement ps, Map<String, String> columnTypeMap, CreateDeleteSql createDeleteSql) throws SQLException {
        List<Map<String, Object>> filter = createDeleteSql.getAndFilterList();
        for (int i = 0; i < filter.size(); i++) {
            Map<String, Object> stringObjectMap = filter.get(i);
            //获取字段
            String field = (String) filter.get(i).get("field");
            //获取字段类型
            String columnType = columnTypeMap.get(field);
            String condition = (String) filter.get(i).get("condition");
            if (condition.equalsIgnoreCase(QueryCondition.SQL_IN)) {
                continue;
            }
            try {
                driverClassName = dataBeanConfig.getDriverClassName();
                if (DataDriver.ORACLE_DRIVER.equals(driverClassName)) {
                    oracleTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i);
                } else if (DataDriver.PG_DRIVER.equals(driverClassName)) {
                    pgTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i);
                } else if (DataDriver.SQLSERVER_DRIVER.equals(driverClassName)) {
                    sqlServerTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i);
                } else if (DataDriver.MYSQL_DRIVER.equals(driverClassName)) {
                    mysqlTypeConversion.dataConversion(ps, columnType, stringObjectMap, "value", i);
                }
            } catch (Exception e) {
                log.error("字段{}类型转换错误{}", field, e);
                e.getMessage();
            }
        }
    }
}
